﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Utils.Collections;

namespace Utils.States
{
    public class StateTransitionEvent : EventArgs, IRecyclable
    {
        State from;
        State to;

        public StateTransitionEvent()
        { 
        }

        public void Init(State from, State to)
        {
            this.from = from;
            this.to = to;
        }

        public void Recycle()
        {
            this.from = null;
            this.to = null;
        }

        public bool StateEntered(StateId stateId)
        {
            State tempFrom = from;
            State tempTo = to;

            if (tempTo.ID == stateId)
            {
                return true;
            }

            // bring both states to the same depth
            while(tempTo.NodeDepth > tempFrom.NodeDepth)
            {
                tempTo = tempTo.Parent;

                if(tempTo.ID == stateId)
                {
                    return true;
                }
            }

            while (tempFrom.NodeDepth > tempTo.NodeDepth)
            {
                tempFrom = tempFrom.Parent;
            }

            //now check target as long as parent of target+source is not the same
            while (tempTo.Parent != tempFrom.Parent)
            {
                tempTo = tempTo.Parent;
                tempFrom = tempFrom.Parent;

                if (tempTo.ID == stateId)
                {
                    return true;
                }
            }

            return false;
        }

        public bool StateLeaved(StateId stateId)
        {
            State tempFrom = from;
            State tempTo = to;

            if (tempFrom.ID == stateId)
            {
                return true;
            }

            //bring both states to the same depth
            while (tempTo.NodeDepth > tempFrom.NodeDepth)
            {
                tempTo = tempTo.Parent;
            }

            while (tempFrom.NodeDepth > tempTo.NodeDepth)
            {
                tempFrom = tempFrom.Parent;

                if (tempFrom.ID == stateId)
                {
                    return true;
                }
            }

            //now check target as long as parent of target+source is not the same
            while (tempTo.Parent != tempFrom.Parent)
            {
                tempTo = tempTo.Parent;
                tempFrom = tempFrom.Parent;

                if (tempFrom.ID == stateId)
                {
                    return true;
                }
            }

            return false;
        }
    }
}
